<script setup lang="ts">
import { useElementBounding, useWindowSize } from '@vueuse/core'
import * as monaco from 'monaco-editor'
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'

import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
import { onBeforeUnmount, onMounted, useTemplateRef, watch } from 'vue'

const { language, theme } = defineProps<{
  language?: string
  theme: 'vs' | 'vs-dark'
}>()

if ((window as any).MonacoEnvironment === undefined) {
  (window as any).MonacoEnvironment = { // 提供一个定义worker路径的全局变量
    getWorker(_: any, label: string) {
      if (label === 'json') {
        return new JsonWorker()
      }
      if (label === 'css' || label === 'scss' || label === 'less') {
        return new CssWorker()
      }
      if (label === 'html' || label === 'handlebars' || label === 'razor') {
        return new HtmlWorker()
      }
      if (label === 'typescript' || label === 'javascript') {
        return new TsWorker()
      }
      return new EditorWorker() // 基础功能文件， 提供了所有语言通用功能 无论使用什么语言，monaco都会去加载他。
    },
  }
}

monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true)

const editorContainer = useTemplateRef('editorContainer')
let editor: monaco.editor.IStandaloneCodeEditor

const model = defineModel<string>({ })

const { top, width } = useElementBounding(editorContainer)
const { height: winHeight } = useWindowSize()
watch(() => winHeight.value, resizeHeight)
function resizeHeight() {
  if (editor && width.value) {
    const h = winHeight.value - top.value - 30
    editor.layout({ height: h, width: width.value })
  }
}

onMounted(() => {
  if (editorContainer.value) {
    editor = monaco.editor.create(editorContainer.value, {
      value: model.value,
      language, // 编辑语言
      theme, // 编辑器主题
      automaticLayout: true, // 自动布局，适应容器大小变化[2](@ref)
      minimap: { enabled: false }, // 关闭小地图[2](@ref)
      lineNumbers: 'on', // 显示行号
      fontSize: 14,
      tabSize: 4,
      scrollBeyondLastLine: false,
    })
    editor.onDidBlurEditorText(() => model.value = editor.getValue())
    resizeHeight()
  }
})

watch(() => model.value, () => {
  editor && editor.setValue(model.value ?? '')
})

onBeforeUnmount(() => {
  if (editor) {
    editor.dispose()
  }
})
</script>

<template>
  <div ref="editorContainer" class="min-h-100 w-full border border-primary border-solid" />
</template>
